<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
  <title>Lesson 11: Simulation with TOSSIM</title>
  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
</head>
<body>

<div class="title">Lesson 11: Simulation with TOSSIM</div>
<div class="subtitle">Last Modified: 18 May 2006</div>

      <p>This lesson introduces the TOSSIM simulator. You will become
        familiar with how to compile TOSSIM and use some of its
        functionality. You will learn how to:</p>

      <p>
        
        <ul>
          
          <li>Compile TOSSIM.</li>
          
          <li>Configure a simulation in Python and C++.</li>
            
          <li>Inspect variables.</li>
              
          <li>Inject packets.</li>
        </ul>
      </p>


<h1>Introduction</h1>

        TOSSIM simulates entire TinyOS applications. It works by
        replacing components with simulation implementations. The
        level at which components are replaced is very flexible: for
        example, there is a simulation implementation of millisecond
        timers that replaces <code>HilTimerMilliC</code>, while there is also an
        implementation for atmega128 platforms that replaces the HPL
        components of the hardware clocks. The former is general and
        can be used for any platform, but lacks the fidelity of
        capturing an actual chips behavior, as the latter
        does. Similarly, TOSSIM can replace a packet-level
        communication component for packet-level simulation, or
        replace a low-level radio chip component for a more precise
        simulation of the code execution.

        TOSSIM is a discrete event simulator. When it runs, it pulls
        events of the event queue (sorted by time) and executes them.
        Depending on the level of simulation, simulation events can
        represent hardware interrupts or high-level system events
        (such as packet reception). Additionally, tasks are simulation
        events, so that posting a task causes it to run a short time
        (e.g., a few microseconds) in the future.

        TOSSIM is a library: you must write a program that configures
        a simulation and runs it. TOSSIM supports two programming
        interfaces, Python and C++. Python allows you to interact with
        a running simulation dynamically, like a powerful
        debugger. However, as the interpretation can be a performance
        bottleneck when obtaining results, TOSSIM also has a C++
        interface. Usually, transforming code from one to the other is
        very simple.

        TOSSIM currently does not support gathering power
        measurements.

        <h1>Compiling TOSSIM</h1>

        <p>TOSSIM is a TinyOS library. Its core code lives in <code><a
        href="../../../tos/lib/tossim">tos/lib/tossim</a></code>. Every TinyOS
        source directory has an optional <code>sim</code> subdirectory,
        which contains simulation implementations of that package. For
        example, <code><a
        href="../../../tos/chips/atm128/timersim">tos/chips/atm128/timer/sim</a></code>
        contains TOSSIM implementations of some of the Atmega128 timer
        abstractions.</p>

        <p>To compile TOSSIM, you pass the <code>sim</code> option to make:</p>

        <pre>
          $ cd apps/Blink
          $ make micaz sim
        </pre>

        
        
      <p>Currently, the only platform TOSSIM supports is the
        micaz. You should see output similar to this:</p>
      <pre>
          mkdir -p build/micaz
            placing object files in build/micaz
            writing XML schema to app.xml
            compiling BlinkAppC to object file sim.o 
          ncc -c -fPIC -o build/micaz/sim.o -g -O0 -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\)   -finline-limit=100000 -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -Wno-nesc-data-race BlinkAppC.nc   -fnesc-dump=components -fnesc-dump=variables -fnesc-dump=constants -fnesc-dump=typedefs -fnesc-dump=interfacedefs -fnesc-dump=tags -fnesc-dumpfile=app.xml
            compiling Python support into pytossim.o and tossim.o
          g++ -c -shared -fPIC -o build/micaz/pytossim.o -g -O0  /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim_wrap.cxx -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim -DHAVE_CONFIG_H
          g++ -c -shared -fPIC -o build/micaz/tossim.o -g -O0  /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim.c -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim
            linking into shared object ./_TOSSIMmodule.so
          g++ -shared build/micaz/pytossim.o build/micaz/sim.o build/micaz/tossim.o -lstdc++ -o _TOSSIMmodule.so
          copying Python script interface TOSSIM.py from lib/tossim to local directory
      </pre>

      <p>Depending on what OS you are using and what packages are installed, TOSSIM may
	not properly compile on the first try. <A HREF="#appendix">Appendix A</A>
	addresses some of the common causes and gives possible solutions.</p>

      <A name="#compiling"></A>

	
        <p>Compiling TOSSIM has five basic steps. Let's go through
        them one by one.</p>

        <h2>Writing an XML schema</h2>

        <pre>
          writing XML schema to app.xml
        </pre>

        <p>The first thing the TOSSIM build process does is use
        nesc-dump to produce an XML document that describes the
        application. Among other things, this document descibes the
        name and type of every variable.</p>

        <h2>Compiling the TinyOS Application</h2>

        <p>Besides introducing all of these new compilation steps, the
        <code>sim</code> option changes the include paths of the
        application. If the application has a series of includes</p>

        <pre>
          -Ia -Ib -Ic
        </pre>

        <p>Then the sim option transforms the list to</p>

        <pre>
          -Ia/sim -Ib/sim -Ic/sim -I%T/lib/tossim -Ia -Ib -Ic
        </pre>
          
        <p>This means that any system-specific simulation
        implementations will be used first, followed by generic TOSSIM
        implementations, followed by standard implementations. The
        <code>sim</code> option also passes a bunch of arguments to the
        compiler, so it knows to compile for simulation.</p>

        <p>The product of this step is an object file, <code>sim.o</code>,
        which lives in the platform's build directory. This object
        file has a set of C functions which configure the simulation
        and control execution.</p>

        <h2>Compiling the Programming Interface</h2>

        <pre>
            compiling Python support into pytossim.o and tossim.o
          g++ -c -shared -fPIC -o build/micaz/pytossim.o -g -O0 \
          /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim_wrap.cxx \
          -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim \
          -DHAVE_CONFIG_H
          g++ -c -shared -fPIC -o build/micaz/tossim.o -g -O0 \
          /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim.c \
          -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim
        </pre>
        
        <p>The next step compiles the support for the C++ and Python
        programming interfaces. The Python interface is actually built
        on top of the C++ interface. Calling a Python object calls a
        C++ object, which then calls TOSSIM through the C
        interface. <code>tossim.o</code> contains the C++ code, while
        <code>pytossim.o</code> contains the Python support. These files
        have to be compiled separately because C++ doesn't understand
        nesC, and nesC doesn't understand C++.</p>

        <h2>Building the shared object</h2>
        
        <pre>
            linking into shared object ./_TOSSIMmodule.so
          g++ -shared build/micaz/pytossim.o build/micaz/sim.o build/micaz/tossim.o -lstdc++ -o _TOSSIMmodule.so
        </pre>

        <p>The next to last step is to build a shared library that
        contains the TOSSIM code, the C++ support, and the Python
        support.</p>

        <h2>Copying Python Support</h2>
        
        <pre>
            copying Python script interface TOSSIM.py from lib/tossim to local directory
        </pre>

        <p>Finally, there is the Python code that calls into the
        shared object. This code exists in <code>lib/tossim</code>, and
        the make process copies it into the local directory.</p>

        
        <h1>Running TOSSIM with Python</h1>
        
        <p>Go into the <code>RadioCountToLeds</code> application and build
          TOSSIM:</p>

        <pre>
$ cd tinyos-2.x/apps/RadioCountToLeds
$ make micaz sim
        </pre>

        <p>We'll start with running a simulation in Python. You can either
          write a script and just tell Python to run it, or you can
          use Python interactively. We'll start with the latter. Fire
          up your Python interpreter:</p>

        <pre>
$ python
        </pre>

        <p>You should see a prompt like this:</p>

        <pre>
Python 2.3.4 (#1, Nov  4 2004, 14:13:38)
[GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
        </pre>

        <p>The first thing we need to do is import TOSSIM and create a
        TOSSIM object. Type</p>

        <pre>
>>> from TOSSIM import *
>>> t = Tossim([])
        </pre>
        
        <p>The square brackets are an optional argument that lets you
        access variables in the simulation. We'll get to how to use
        that later. In this case, we're telling TOSSIM that there are
        no variables that we want to look at. The way you run a TOSSIM
        simulation is with the <code>runNextEvent</code> function. For
        example:</p>

        <pre>
>>> t.runNextEvent()
0
        </pre>

        <p>When you tell TOSSIM to run the next event, it returns
        0. This means that there was no next event to run. The reason
        is simple: we haven't told any nodes to boot. This snippet of
        code will tell mote 32 to boot at time 45654 and run its first
        event (booting):</p>

        <pre>
>>> m = t.getNode(32);
>>> m.bootAtTime(45654);
>>> t.runNextEVent()
1
        </pre>

      <p>Instead of using raw simulation ticks, you can also use the
      call <code>ticksPerSecond()</code>. However, you want to be careful
      to add some random bits into this number: having every node
      perfectly synchronized and only different in phase in terms of
          seconds can lead to strange results.</p>

      <pre>
>>> m = t.getNode(32);
>>> m.bootAtTime(4 * t.ticksPerSecond() + 242119);
>>> t.runNextEVent()
1
      </pre>

        <p>Now, <code>runNextEvent</code> returns 1, because there was an
        event to run. But we have no way of knowing whether the node
        has booted or not. We can find this out in one of two ways.
        The first is that we can just ask it:</p>

        <pre>
>>> m.isOn()
1
>>> m.turnOff()
>>> m.isOn()
0
>>> m.bootAtTime(560000)
>>> t.runNextEvent()
0
>>> t.runNextEvent()
1
        </pre>        

        <p>Note that the first <code>runNextEvent</code> returned 0. This
        is because when we turned the mote off, there was still an
        event in the queue, for its next timer tick. However, since
        the mote was off when the event was handled in that call,
        <code>runNextEvent</code> returned 0. The second call to
        <code>runNextEvent</code> returned 1 for the second boot event, at
        time 560000.</p>


        <p>A Tossim object has several useful functions. In Python,
        you can generally see the signature of an object with the
        <code>dir</code> function. E.g.:</p>

        <pre>
>>> t = Tossim([])
>>> dir(t)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__getattr__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__swig_getmethods__', '__swig_setmethods__', '__weakref__', 'addChannel',
'currentNode', 'getNode', 'init', 'mac', 'newPacket', 'radio', 'removeChannel',
'runNextEvent', 'setCurrentNode', 'setTime', 'this', 'thisown', 'time', 'timeStr']
        </pre>

        <p>The most common utility functions are:</p>

        <ul>
          <li><b><code>currentNode()</code></b>: returns the ID of the current node.</li>
          <li><b><code>getNode(id)</code></b>: returns an object representing a specific mote</li>
          <li><b><code>runNextEvent()</code></b>: run a simulation event</li>
          <li><b><code>time()</code></b>: return the current time in simulation ticks as a large integer </li>
          <li><b><code>timeStr()</code></b>: return a string representation of the current time</li>
          <li><b><code>init()</code></b>: initialize TOSSIM</li>
          <li><b><code>mac()</code></b>: return the object representing the media access layer</li>
          <li><b><code>radio()</code></b>: return the object representing the radio model</li>
          <li><b><code>addChannel(ch, output)</code></b>: add <i>output</i> as an output to channel <i>ch</i> </li>
          <li><b><code>removeChannel(ch, output)</code></b>: remove <i>output</i> as an output to channel <i>ch</i> </li>
          <li><b><code>ticksPerSecond()</code></b>: return how many simulation ticks there are in a simulated second </li>
        </ul>

        <p>The next section discusses the last two.</p>

          <h1>Debugging Statements</h1>
        
        <p>The second approach to know whether a node is on is to tell
        it to print something out when it boots. TOSSIM has a
        debugging output system, called <code>dbg</code>. There are four
        <code>dbg</code> calls:</p>

          <ul>
            <li><code>dbg</code>: print a debugging statement preceded by the node ID.</li>
            <li><code>dbg_clear</code>: print a debugging statement which is not preceded by the node ID. This allows you to easily print out complex data types, such as packets, without interspersing node IDs through the output.</li>
            <li><code>dbgerror</code>: print an error statement preceded by the node ID</li>
            <li><code>dbgerror_clear</code>: print an error statement which is not preceded by the node ID</li>
          </ul>

          
        <p>Go into <code>RadioCountToLedsC</code> and modify the <code>Boot.booted</code> event
          to print out a debug message when it boots, such as this:</p>

        <pre>
event void Boot.booted() {
  call Leds.led0On();
  dbg("Boot", "Application booted.\n");
  call AMControl.start();
}
        </pre>

        <p>Calls to the debugging calls take two or more
        parameters. The first parameter ("Boot" in the above example)
        defines the output <i>channel</i>. An output channel is simply
        a string. The second and subsequent parameters are the message
        to output. They are identical to a printf statement. For example
          <code>RadioCountToLedsC</code> has this call:

        <pre>
event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {
  dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
  ...
}
        </pre>

        which prints out the length of received packet as an 8-bit unsigned value (%hhu).</p>

        <p>Once you have added the debugging statement to the event,
        recompile the application with <code>make micaz sim</code> and
        start up your Python interpreter. Load the TOSSIM module and
        schedule a mote to boot as before:</p>
        
        <pre>
>>> from TOSSIM import *
>>> t = Tossim([])
>>> m = t.getNode(32);
>>> m.bootAtTime(45654);
        </pre>

        <p>This time, however, we want to see the debugging message
        that the mote has booted. TOSSIM's debugging output can be
        configured on a per-channel basis. So, for example, you can
        tell TOSSIM to send the "Boot" channel to standard output, but
        another channel, say "AM", to a file. 
        By default, a channel has no destination, and so
        messages to it are discarded.</p>

        <p>In this case, we want to send the Boot channel to standard
        output. To do this, we need to import the <code>sys</code> Python
        package, which lets us refer to standard out. We can then tell
        TOSSIM to send Boot messages to this destination:
          
        <pre>
>>> import sys
>>> t.addChannel("Boot", sys.stdout);
1
        </pre>

          The return value shows that the channel was added successfully. Run the first
          simulation event, and the mote boots:

        <pre>
>>> t.runNextEvent()
DEBUG (32): Application booted.
1
        </pre>          </p>

        <p>The only difference between debug and error functions is
        the string output at the beginning of a message. Debug
        statements print <code>DEBUG (n)</code>, while error statements
        print <code>ERROR (n)</code>.</p>

        <p>A debugging statement can have multiple output
          channels. Each channel name is delimited by commas:

          <pre>
event void Boot.booted() {
  call Leds.led0On();
  dbg("Boot,RadioCountToLedsC", "Application booted.\n");
  call AMControl.start();
}
          </pre>

          If a statement has multiple channels and those channels
          share outputs, then TOSSIM only prints the message once. For
          example, if both the Boot channel and RadioCountToLedsC
          channel were connected to standard out, TOSSIM will only
          print one message. For example, this series of debug statements

          
          <pre>
event void Boot.booted() {
  call Leds.led0On();
  dbg("Boot,RadioCountToLedsC", "Application booted.\n");
  dbg("RadioCountToLedsC", "Application booted again.\n");
  dbg("Boot", "Application booted a third time.\n");
  call AMControl.start();
}
          </pre>

          when configured so

          <pre>
>>> import sys
>>> t.addChannel("Boot", sys.stdout)
>>> t.addChannel("RadioCountToLedsC", sys.stdout)
          </pre>

          will print out this:

          <pre>
DEBUG (32): Application booted.
DEBUG (32): Application booted again.
DEBUG (32): Application booted a third time.
          </pre></p>


        <p>A channel can have multiple outputs. For example, this
        script will tell TOSSIM to write <code>RadioCountToLedsC</code> messages to
        standard output, but to write <code>Boot</code> messages to both standard
        output and a file named <code>log.txt</code>:

          <pre>
>>> import sys
>>> f = open("log.txt", "w")
>>> t.addChannel("Boot", f)
>>> t.addChannel("Boot", sys.stdout)
>>> t.addChannel("RadioCountToLedsC", sys.stdout)
          </pre>
        </p>

        <h1>Configuring a Network</h1>

        <p>When you start TOSSIM, no node can communicate with any
        other.  In order to be able to simulate network behavior, you
        have to specify a <i>network topology</i>. Internally, TOSSIM
        is structured so that you can easily change the underlying
        radio simulation, but that's beyond the scope of this
        tutorial. The default TOSSIM radio model is signal-strength
        based. You provide a graph to the simulator that describes the
        propagation strengths. You also specify noise floor, and
        receiver sensitivity. There are some very early results that
        describe current sensor platforms (e.g., the mica2) in these
        terms. Because all of this is through a scripting interface,
        rather than provide a specific radio model, TOSSIM tries to
        provide a few low-level primitives that can express a wide
        range of radios and behavior.</p>

        <p>You control the radio simulation through a Python Radio
        object:</p>

        
        <pre>
>>> from TOSSIM import *
>>> t = Tossim([])
>>> r = t.radio()
>>> dir(r)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__',
'__getattr__', '__getattribute__', '__hash__', '__init__',
'__module__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', '__swig_getmethods__',
'__swig_setmethods__', '__weakref__', 'add', 'connected',
'gain', 'remove', 'setNoise', 'this', 'thisown',
<class 'TOSSIM.RadioPtr'>]
        </pre>          

        <p>The first set of methods (with the double underscores) are
        ones that you usually don't call. The important ones are at
        the end. They are:</p>

        <ul>
          <li><b><code>add(src, dest, gain)</code></b>: Add a link from <i>src</i>
          to <i>dest</i> with <i>gain</i>. When <i>src</i> transmits, <i>dest</i>
          will receive a packet attenuated by the <i>gain</i> value.</li>

          <li><b><code>connected(src, dest)</code></b>: Return whether there is a
          link from <i>src</i> to <i>dest</i>.</li>


          <li><b><code>gain(src, dest)</code></b>: Return the gain value of the
          link from <i>src</i> to <i>dest</i>.</li>
          
          <li><b><code>remove(src, dest)</code></b>: Remove the link from
          <i>src</i> to <i>dest</i>.</li>


          <li><b><code>setNoise(node, mean, variance)</code></b>: Set the noise
          floor at <i>node</i> to be a gaussian distribution with
          <i>mean</i> and <i>variance</i>.</li>

          <li><b><code>sensitivity()</code></b>: Return the receive sensitivity of
            the nodes.</li>

          <li><b><code>setSensitivity(val)</code></b>: Set the receive sensitivity
          of nodes to be <i>val</i>. The sensitivity is how much
          stronger a signal must be for it to be received
          uncorrupted. E.g., a sensitivity of 3.0 (the default value)
          means that a packet must be 3dBm greater than the sum of
          noise and concurrent transmissions for it to be received
          uncorrupted.</li>

          <li><b><code>threshold()</code></b>: Return the CCA threshold.</li>

          <li><b><code>setThreshold(val)</code></b>: Set the CCA threshold value in
            dBm.The default is -95.</li>
          
        </ul>

        <p>The Radio object only deals with physical layer
        propagation. The MAC object deals with the data link layer,
        packet lengths, and radio bandwidth. The default TOSSIM MAC
        object is for a CSMA protocol. You get a reference to the MAC
        object by calling <code>mac()</code> on a Tossim object:
          <pre>
>>> mac = t.mac()
          </pre>

          The default MAC object has a large number of functions, for
          controlling backoff behavior, packet preamble length, radio
          bandwidth, etc. All time values are specified in terms of
          radio symbols, and you can configure the number of symbols
          per second and bits per symbol. By default, the MAC object
          is configured to act like the standard TinyOS 2.0 CC2420
          stack: it has 4 bits per symbol and 64k symbols per second,
          for 256kbps. This is a subset of the MAC functions that
          could be useful for changing backoff behavior. Every
          accessor function has a corresponding set function that
          takes an integer as a parameter. E.g., there's <code>int
          initHigh()</code> and <code>void setInitHigh(int val)</code>. The
          default value for each parameter is shown italicized in
          parentheses.  </p>

        <ul>
          <li><b>initHigh</b>: The upper bound of the initial backoff range. <i>(400)</i></li>
          <li><b>initLow</b>: The lower bound of the initial backoff range. <i>(20)</i></li>
          <li><b>high</b>: The upper bound of the backoff range. This is multiplied by the
          exponent base to the nth power, where n is the number of previous backoffs. So if the
          node had its initial backoff, then the upper bound is high * base, while if it
          is after the second backoff then the upper bound is high * base * base. <i>(160)</i></li>
          <li><b>low</b>: The lower bound of the backoff range. This is multiplied by the
          exponent base to the nth power, where n is the number of previous backoffs. So if the
          node had its initial backoff, then the upper bound is low * base, while if it
          is after the second backoff then the upper bound is low * base * base. <i>(20)</i></li>
          <li><b>symbolsPerSec</b>: The number of symbols per second that the radio can
          transmit. <i>(65536)</i></li>
          <li><b>bitsPerSymbol</b>: The number of bits per radio symbol. Multiplying this by
          the symbols per second gives the radio bandwidth. <i>(4)</i></li>
          <li><b>preambleLength</b>: How long a packet preamble is. This is added to the duration
          of transmission for every packet. <i>(12)</i></li>
          <li><b>exponentBase</b>: The base of the exponent used to calculate backoff. Setting it to
          2 provides binary exponential backoff. <i>(0)</i>.</li>
          <li><b>maxIterations</b>: The maximum number of times the radio will back off before
          signaling failure, zero signifies forever. <i>(0)</i>.</li>
          <li><b>minFreeSamples</b>: The number of times the radio must detect a clear channel
          before it will transmit. This is important for protocols like 802.15.4, whose synchonrous
          acknowledgments requires that this be greater than 1 (you could have sampled in the dead time
          when the radios are changing between RX and TX mode). <i>(2)</i></li>
          <li><b>rxtxDelay</b>: The time it takes to change the radio from RX to TX mode (or vice versa).<i>(32)</i></li>
          <li><b>ackTime</b>: The time it takes to transmit a synchonrous acknowledgment, not including the
          requisite RX/TX transition.<i>(34)</i></li>
        </ul>

        <p>Any and all of these configuration constants can be changed
        at compile time with #define directives. Look at
        <code>tos/lib/tossim/sim_csma.h</code>.</p>

        <p>Because the radio connectivity graph can be scripted, you
        can easily store topologies in files and then load the
        file. Alternatively, you can store a topology as a script.
        For example, this script will load a file which specifies each
          link in the graph as a line with three values, the source, the
          destination, and the gain, e.g.:

          <pre>
1  2 -54.0
          </pre>

          means that when 1 transmits 2 hears it at -54 dBm. Create a file <code>topo.txt</code>
          that looks like this:</p>

        <pre>
1  2 -54.0
2  1 -55.0
1  3 -60.0
3  1 -60.0
2  3 -64.0
3  2 -64.0
        </pre>

        <p>This script will read such a file:

          <pre>
>>> f = open("topo.txt", "r")
>>> lines = f.readlines()
>>> for line in lines:
...   s = line.split()
...   if (len(s) > 0):
...     print " ", s[0], " ", s[1], " ", s[2];
...     r.add(int(s[0]), int(s[1]), float(s[2]))
          </pre></p>
        
        
        <p>Now, when a node transmits a packet, other nodes will hear it.
        This is a complete script for simulating packet transmission with
          RadioCountToLedsC. Save it as a file <code>test.py</code>:</p>
        <pre>
from TOSSIM import *
import sys

t = Tossim([])
r = t.radio()
f = open("topo.txt", "r")

lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    print " ", s[0], " ", s[1], " ", s[2];
    r.add(int(s[0]), int(s[1]), float(s[2]))

t.addChannel("RadioCountToLedsC", sys.stdout)
t.addChannel("Boot", sys.stdout)

t.getNode(1).bootAtTime(100001);
t.getNode(2).bootAtTime(800008);
t.getNode(3).bootAtTime(1800009);

r.setNoise(1, -100.0, 5.0)
r.setNoise(2, -100.0, 5.0)
r.setNoise(3, -100.0, 5.0)

for i in range(0, 100):
  t.runNextEvent()
        </pre>          

        <p>Run it by typing <code>python test.py</code>. You should see
          output that looks like this:</p>

        <pre>
1  2 -54.0
2  1 -55.0
1  3 -60.0
3  1 -60.0
2  3 -64.0
3  2 -64.0
DEBUG (1): Application booted.
DEBUG (1): Application booted again.
DEBUG (1): Application booted a third time.
DEBUG (2): Application booted.
DEBUG (2): Application booted again.
DEBUG (2): Application booted a third time.
DEBUG (3): Application booted.
DEBUG (3): Application booted again.
DEBUG (3): Application booted a third time.
DEBUG (1): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (1): RadioCountToLedsC: packet sent.
DEBUG (2): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (2): RadioCountToLedsC: packet sent.
DEBUG (3): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (3): RadioCountToLedsC: packet sent.
DEBUG (1): Received packet of length 2.
DEBUG (3): Received packet of length 2.
DEBUG (2): Received packet of length 2.
DEBUG (1): RadioCountToLedsC: timer fired, counter is 2.
DEBUG (1): RadioCountToLedsC: packet sent.
DEBUG (2): RadioCountToLedsC: timer fired, counter is 2.
DEBUG (2): RadioCountToLedsC: packet sent.
DEBUG (3): RadioCountToLedsC: timer fired, counter is 2.
DEBUG (3): RadioCountToLedsC: packet sent.
DEBUG (1): Received packet of length 2.
        </pre>

        <p>If you set the noise to be 30 plus or minus 5 dBm instead
        of 80 plus or minus 5 dBm, then nodes will never transmit, as
        the default CCA threshold is -95 dBm. You'll see something
        like this:</p>
             <pre>
1  2 -54.0
2  1 -55.0
1  3 -60.0
3  1 -60.0
2  3 -64.0
3  2 -64.0
DEBUG (1): Application booted.
DEBUG (1): Application booted again.
DEBUG (1): Application booted a third time.
DEBUG (2): Application booted.
DEBUG (2): Application booted again.
DEBUG (2): Application booted a third time.
DEBUG (3): Application booted.
DEBUG (3): Application booted again.
DEBUG (3): Application booted a third time.
DEBUG (1): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (1): RadioCountToLedsC: packet sent.
DEBUG (2): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (2): RadioCountToLedsC: packet sent.
DEBUG (3): RadioCountToLedsC: timer fired, counter is 1.
DEBUG (3): RadioCountToLedsC: packet sent.
DEBUG (1): RadioCountToLedsC: timer fired, counter is 2.
DEBUG (2): RadioCountToLedsC: timer fired, counter is 2.
DEBUG (3): RadioCountToLedsC: timer fired, counter is 2.
        </pre>

        <p>Because the nodes backoff perpetually, they never transmit
        the packet and so subsequent attempts to send fail. Although
        it only takes a few simulation events to reach the first timer
        firings, it takes many simulation events (approximately 4000)
        to reach the second timer firings. This is because the nodes
        have MAC backoff events. If you want to simulate in terms of
        time, rather than events, you can always do something like
        this, which simulates 5 seconds from the first node boot:</p>

        <pre>
t.runNextEvent();
time = t.time()
while (time + 50000000000 > t.time()):
  t.runNextEvent()
</pre>

        <p>TOSSIM allows you to specify a network topology in terms of
        gain. However, this raises the problem of coming up with a
        topology. There are two approaches you can take. The first is
        to take data from a real world network and input this into
        TOSSIM. The second is to generate it from applying a
        theoretical propagation model to a physical layout.  The standard
        file format is

          <pre>
noise n avg std
gain src dest g
          </pre>

          where each statement is on a separate line. The <i>noise</i>
          statement defines the noise observed at node <i>n</i> with
          an average of <i>avg</i> and a standard deviation of
          <i>std</i>.  The <i>gain</i> statement defines a propagation
          gain <i>g</i> when <i>src</i> transmits to <i>dest</i>. This
          is a snippet of python code that will parse this file
          format:

          <pre>
f = open("mirage-1.txt", "r")

lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    if (s[0] == "gain"):
      r.add(int(s[1]), int(s[2]), float(s[3]))
    elif (s[0] == "noise"):
      r.setNoise(int(s[1]), float(s[2]), float(s[3]))
          </pre></p>

        <p>TOSSIM has a tool for the second option of generating a
        network topology using a theoretical propagation model. The
        tool is written in Java and is
        <code>net.tinyos.sim.PropagationModel</code>. The tool takes a
        single command line parameter, the name of a configuration
        file, e.g.:</p>

        <pre>
java net.tinyos.sim.PropagationModel config.txt
        </pre>

        <p>The format of a configuration file is beyond the scope of
        this document: the tool has its own <A
        HREF="usc-topologies.html">documentation</A>. TOSSIM has two sample configuration
        files generated from the tool in
        <code>tos/lib/tossim/topologies</code>. The first is <code><A
        HREF="">grid.txt</A></code>, which is a 10x10 grid of nodes
        spaced roughly 40 feet apart. Each node is placed randomly
        within a 40'x40' "cell." The cells follow a strict grid. The
        second file is <code><A HREF="">scatter.txt</A></code>, which is
        100 nodes scattered randomly (with a uniform distribution)
        over a 360'x360' area. Note that the tool uses random numbers,
        these configuration files can generate multiple different
        network topologies. Network topology files generated from the
        tool follow the same format as <code>mirage-1.txt</code>.</p>

        <h1>Variables</h1>

        <p>TOSSIM allows you to inspect variables in a running TinyOS
        program. Currently, you can only inspect basic types. For
        example, you can't look at fields of structs, but you can look
        at state variables.</p>

        <p>When you compile TOSSIM, the make system generates a large
        XML file that contains a lot of information about the TinyOS
        program, including every component variable and its type. If
        you want to examine the state of your program, then you need
        to give TOSSIM this information so it can parse all of the
        variables properly. You do this by instantiating a Python
        object that parses the XML file to extract all of the relevant
        information. You have to import the Python support package for
        TOSSIM to do this:</p>

        <pre>
from tinyos.tossim.TossimApp import *

n = NescApp()
        </pre>

        <p>Instantiating a <code>NescApp</code> can take quite a while:
        Python has to parse through megabytes of XML. So be patient
        (you only have to do it once). NescApp has two optional
        arguments. The first is the name of the application being
        loaded. The second is the XML file to load. The default for
        the latter is <code>app.xml</code>, which is the name of the file
        that the make system generates. The default for the former is
        "Unknown App."  So this code behaves identically to that
        above:</p>

        <pre>
from tinyos.tossim.TossimApp import *

n = NescApp("Unknown App", "app.xml")
        </pre>

        <p>You fetch a list of variables from a NescApp object by
        calling the function <code>variables</code> on the field
        <code>variables</code>:</p>

        <pre>
vars = n.variables.variables()
        </pre>

        <p>To enable variable inspection, you pass this list to a
        Tossim object when you instantiate it:</p>

        <pre>
t = Tossim(vars)
        </pre>

        <p>The TOSSIM object now knows the names, sizes, and types of
        all of the variables in the TinyOS application. This
        information allows the TOSSIM support code to take C variables
        and properly tranform them into Python variables. This
        currently only works for simple types: if a component declares
        a structure, you can't access its fields. But let's say we
        want to read the counter in <code>RadioCountToLedsC</code>. Since each mote
        in the network has its own instance of the variable, we need
        to fetch it from a specific mote:</p>

        <pre>
m = t.getNode(0)
v = m.getVariable("RadioCountToLedsC.counter")
        </pre>

        <p>The name of a variable is usually <i>C.V</i>, where
        <i>C</i> is the component name and <i>V</i> is the variable.
        In the case of generic components, the name is <i>C.N.V</i>,
        where <i>N</i> is an integer that describes which instance.
        Unfortunately, there is currently no easy way to know what
        <i>N</i> is from nesC source, so you have to root through
        <code>app.c</code> in order to know.</p>

        <p>Once you have a variable object (<code>v</code> in the above
        code), you can fetch its value with the <code>getData()</code>
        function:</p>

        <pre>
counter = v.getData()
        </pre>

        <p>Because <code>getData()</code> transforms the underlying C type
        into a Python type, you can then use its return value in
        Python expressions. For example, this script will start a
        simulation of five nodes and run it until node 0's counter
        reaches 10:</p>

        <pre>
from sys import *
from random import *
from TOSSIM import *
from tinyos.tossim.TossimApp import *

n = NescApp()
t = Tossim(n.variables.variables())
r = t.radio()

f = open("topo.txt", "r")
lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    if (s[0] == "gain"):
      r.add(int(s[1]), int(s[2]), float(s[3]))
    elif (s[0] == "noise"):
      r.setNoise(int(s[1]), float(s[2]), float(s[3]))

for i in range (0, 4):
  m = t.getNode(i)
  m.bootAtTime(randint(1000, 2000) * 1000000)

m = t.getNode(0)
v = m.getVariable("RadioCountToLedsC.counter")

while (v.getData() < 10):
  t.runNextEvent()

        </pre>

      <p>The TOSSIM <A
      HREF="../../../tos/lib/tossim/examples">examples</A>
      subdirectory also has an example script, named
      <code>variables.py</code>.</p>

      <h1>Injecting Packets</h1>

      <p>TOSSIM allows you to dynamically inject packets into a
      network.  Packets can be scheduled to arrive at any time. If a
      packet is scheduled to arrive in the past, then it arrives
      immediately. Injected packets circumvent the radio stack: it is
      possible for a node to receive an injected packet while it is in
      the midst of receiving a packet from another node over its
      radio.</p>

      <p>TinyOS 2.0 has support for building Python packet objects.
      Just like the standard Java toolchain, you can build a packet
      class based on a C structure. The packet class gives you a full
      set of packet field mutators and accessors. If an application
      has a packet format, you can generate a packet class for it,
      instantiate packet objects, set their fields, and have nodes
      receive them.</p>

      <p>The <code>RadioCountToLeds</code> application Makefile has an
      example of how to do this. First, it adds the Python class as a
      dependency for building the application. Whenever you compile
      the app, if the Python class doesn't exist, make will build it
      for you:</p>

      <pre>
BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class
      </pre>

      <p>The Makefile also tells make how to generate RadioCountMsg.py:</p>

      <pre>
RadioCountMsg.py: RadioCountToLeds.h
        mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
      </pre>

      <p>The rule says to generate RadioCountMsg.py by calling mig
      with the python parameter.  The Makefile also has rules on how
      to build Java class, but that's not important for TOSSIM. Since
      we've been using RadioCountToLeds so far, the Python class
      should be there already.</p>

      <p>RadioCountMsg.py defines a packet format, but this packet is
      contained in the data payload of another format. If a node is
      sending a <code>RadioCountMsg</code> over AM, then the <code>RadioCountMsg</code>
      structure is put into the AM payload, and might look something
      like this:</p>

      <center>
        <table BORDER=1>
          <TR>
            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Header</TD>
            <TD WIDTH=100 BGCOLOR="white">RadioCountMsg</TD>
            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Footer</TD>
          </TR>
        </table>
      </center>
      
      <p>If it is sending it over a routing protocol. the packet is
      put in the routing payload, and might look something like this:</p>

      <center>
        <table BORDER=1>
          <TR>
            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Header</TD>
            <TD WIDTH=100 BGCOLOR="#00a0ff">Routing Header</TD>
            <TD WIDTH=100 BGCOLOR="white">RadioCountMsg</TD>
            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Footer</TD>
          </TR>
        </table>
      </center>

      <p>If you want to send a <code>RadioCountMsg</code> to a node, then you need
      to decide how to deliver it. In the simple AM case, you place
      the <code>RadioCountMsg</code> structure in a basic AM packet. In the routing
      case, you put it in a routing packet, which you then put inside
      an AM packet. We'll only deal with the simple AM case here.</p>

      <p>To get an AM packet which you can inject into TOSSIM, you
      call the <code>newPacket</code> function on a Tossim object. The
      returned object has the standard expected AM fields:
      <i>destination</i>, <i>length</i>, <i>type</i>, and <i>data</i>,
      as well as <i>strength</i>.</p>

      <p>To include support for a packet format, you must import
      it. For example, to include <code>RadioCountMsg</code>, you have to import
      it:</p>

      <pre>
from RadioCountMsg import *
      </pre>
      
      <p>This snippet of code, for example, creates a <code>RadioCountMsg</code>,
      sets its counter to 7, creates an AM packet, stores the
      <code>RadioCountMsg</code> in the AM packet, and configures the AM packet so
      it will be received properly (destination and type):</p>

      <pre>
from RadioCountMsg import *

msg = RadioCountMsg()
msg.set_counter(7);
pkt = t.newPacket();
pkt.setData(msg.data)
pkt.setType(msg.get_amType())
pkt.setDestination(0)
      </pre>


      <p>The variable <code>pkt</code> is now an Active Message of the AM
      type of <code>RadioCountMsg</code> with a destination of 0 that contains a
      <code>RadioCountMsg</code> with a counter of 7. You can deliver this packet
      to a node with the <code>deliver</code> function. The
      <code>deliver</code> function takes two parameters, the destination
      node and the time to deliver:</p>

      <pre>
pkt.deliver(0, t.time() + 3)
      </pre>

      <p>This call delivers pkt to node 0 at the current simulation
      time plus 3 ticks (e.g., 3ns). There is also a
      <code>deliverNow</code>, which has no time parameter. Note that if
      the destination of <code>pkt</code> had been set to 1, then the
      TinyOS application would not receive the packet, as it was
      delivered to node 0.</p>

      <p>Taken all together, the following script starts a simulation,
      configures the topology based on topo.txt, and delivers a packet
      to node 0. It can also be found as <code>packets.py</code> in the TOSSIM <A
      HREF="../../../tos/lib/tossim/examples/">examples</A>
      subdirectory.

      <pre>
import sys
from TOSSIM import *
from RadioCountMsg import *

t = Tossim([])
m = t.mac();
r = t.radio();

t.addChannel("RadioCountToLedsC", sys.stdout);
t.addChannel("LedsC", sys.stdout);

for i in range(0, 2):
  m = t.getNode(i);
  m.bootAtTime((31 + t.ticksPerSecond() / 10) * i + 1);
  
f = open("topo.txt", "r")
lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    if (s[0] == "gain"):
      r.add(int(s[1]), int(s[2]), float(s[3]))
    elif (s[0] == "noise"):
      r.setNoise(int(s[1]), float(s[2]), float(s[3]))

for i in range(0, 60):
  t.runNextEvent();

msg = RadioCountMsg()
msg.set_counter(7);
pkt = t.newPacket();
pkt.setData(msg.data)
pkt.setType(msg.get_amType())
pkt.setDestination(0)

print "Delivering " + msg.__str__() + " to 0 at " + str(t.time() + 3);
pkt.deliver(0, t.time() + 3)


for i in range(0, 20):
  t.runNextEvent();
      </pre>

      
      <h1>C++</h1>

      <p>Python is very useful because it is succinct, easy to write,
      and can be used interactively. Interpretation, however, has a
      significant cost: a Python/C transition on every event is a
      significant cost (around 100%, so it runs at half the
      speed). Additionally, it's often useful to step through code
      with a standard debugger. TOSSIM also has support for C++, so
      that it can be useful in these circumstances.  Because many of
      the Python interfaces are merely wrappers around C++ objects,
      much of the scripting stays the same. The two major exceptions
      are inspecting variables and injecting packets.</p>

      <p>In a C++ TOSSIM, there is no variable inspection. While it is
      possible to request memory regions and cast them to the expected
      structures, currently there is no good and simple way to do
      so. The Python support goes through several steps in order to
      convert variables into Python types, and this gets in the way of
      C++. However, as the purpose of C++ is usually to run high
      performance simulations (in which inspecting variables is a big
      cost) or debugging (when you have a debugger), this generally
      isn't a big problem.</p>

      <p>There is a C++ <code>Packet</code> class, which the Python
      version is a simple wrapper around. In order to inject packets
      in C++, however, you must build C support for a packet type and
      manually build the packet. There currently is no support in mig
      with which to generate C/C++ packet structures, and since most
      packets are nx_struct types, they cannot be parsed by
      C/C++. Furthermore, as many of the fields are nx types, they are
      big endian, while x86 processors are little endian. Still, if you
      want to deliver a packet through C++, you can do so.</p>

      <p>Usually, the C++ and Python versions of a program look pretty
      similar. For example:</p>

      <table WIDTH=800>

        <TR><TD WIDTH=400><TD WIDTH=400></TR>
        <TR><TD ALIGN=CENTER><b>Python</b></TD><TD ALIGN=CENTER><b>C++</b></TD></TR>
        <TR>
          <TD VALIGN=TOP>
            <PRE>
import TOSSIM
import sys

from RadioCountMsg import *

t = TOSSIM.Tossim([])
r = t.radio();

for i in range(0, 999):
  m = t.getNode(i);
  m.bootAtTime(5000003 * i + 1);
  r.setNoise(i, -99.0, 3.0);
  for j in range (0, 2):
    if (j != i):
      r.add(i, j, -50.0);




for i in range(0, 1000000):
  t.runNextEvent();
           </PRE>
          </TD>
          <TD VALIGN=TOP>
            <PRE>
#include &lt;tossim.h&gt;



int main() {
  Tossim* t = new Tossim(NULL);
  Radio* r = t->radio();

  for (int i = 0; i &lt; 999; i++) {
    Mote* m = t->getNode(i);
    m->bootAtTime(5000003 * i + 1);
    r->setNoise(i, -99.0, 3);
    for (int j = 0; j &lt; 2; j++) {
      if (i != j) {
        r->add(i, j, -50.0);
      }
    }
  }

  for (int i = 0; i &lt; 1000000; i++) {
    t->runNextEvent();
  }
}
            </PRE>
          </TD>
        </TR>
      </TABLE>

      <p>To compile a C++ TOSSIM, you have to compile the top-level
      driver program (e.g, the one shown above) and link it against
      TOSSIM. Usually the easiest way to do this is to link it against
      the TOSSIM objects rather than the shared library. Often, it's
      useful to have a separate Makefile to do this with. E.g.,
      <code>Makefile.Driver</code>:</p>

      <pre>
all:
        make micaz sim
        g++ -g -c -o Driver.o Driver.c -I../../tos/lib/tossim/
        g++ -o Driver Driver.o build/micaz/tossim.o build/micaz/sim.o build/micaz/c-support.o
      </pre>
        

     <h2>Using gdb</h2>

     <p>Since Driver is a C++ program, you can use gdb on it to
     step through your TinyOS code, inspect variables, set 
     breakpoints, and do everything else you can normally do.
     Unfortunately, as gdb is designed for C and not nesC, the
     component model of nesC means that a single command can have multiple
providers; referring to a specific command requires specifying the component,
interface, and command. For example, to break on entry to the <tt>redOff</tt>
command of the <tt>Leds</tt> interface of <tt>LedsC</tt>, one must type:

<pre>
$ gdb Driver
GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) break *LedsP$Leds$led0Toggle
Breakpoint 1 at 0x804f184: file LedsP.nc, line 73.
</pre>

<p>nesC translates component names to C names using
$. $ is a legal but almost-never-used character in some versions
of C, so nesC prohibits it and uses it internally. The leading
* is necessary so dbg can parse the $s. With the above
breakpoint set, gdb will break whenever a mote toggles led0.</p>

<p>Variables have similar names. For example, to inspect the packet
of RadioCountToLedsC in the RadioCountToLeds application,</p>

<pre>
(gdb) print RadioCountToLedsC$packet
$1 = {{header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
        data = ""}}, data = {{data = ""} <repeats 28 times>}, footer = {{
        data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
        data = ""}, {data = ""}, {data = ""}}} <repeats 1000 times>}
</pre>

<p>For those who know gdb very well, you'll recognize this as a print
of an array, rather than a single variable: there are more than 1000
instances of the message_t struct. This is because TOSSIM simulates
many motes; rather than there being a single RadioCountToLedsC$packet,
there is one for every node. To print the packet of a specific node, you
have to index into the array. This, for example, will print the variable
for node 6:</p>

<pre>
(gdb) print RadioCountToLedsC$packet[6]
$2 = {header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
      data = ""}}, data = {{data = ""} <repeats 28 times>}, footer = {{
      data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
      data = ""}, {data = ""}, {data = ""}}}
</pre>

<p>If you want to print out the variable for the node TOSSIM is currently
simulating, you can do this:</p>

<pre>
(gdb) print RadioCountToLedsC$counter[sim_node()]
$4 = 0
</pre>

<p>You can also set watchpoints (although, as to be expected, they are
<i>slow</i>:</p>

<pre>
(gdb) watch UscGainInterferenceModelC$receiving[23]
Hardware watchpoint 2: UscGainInterferenceModelC$receiving[23]
</pre>

<p>This variable happens to be an internal variable in the 
packet-level network simulation, which keeps track of whether
the radio thinks it is receiving a packet. So setting the
above watchpoint will cause gdb to break whenever 
node 23 starts receiving a packet or returns to searching
for packet preambles.</p>

<p>Generic components add another wrinkle. Since they use
a code-copying approach, each instance of a generic has its
own separate functions and variables (this is mostly due to the
fact that you can pass types to them). Take, for example,
<code>AMQueueImplP</code>, which is used in both the radio
AM stack and the serial AM stack. If you use gdb on an
application that uses both serial and radio communication and
try to break on its Send.send, you'll see an error:</p>

<pre>
(gdb) break *AMQueueImplP$Send$send
No symbol "AMQueueImplP$Send$send" in current context.
</pre>

<p>nesC gives each generic a unique number. So if you
have an application in which there is a single copy
of AMQueueImplP, its name will actually be AMQueueImplP$0.
For example, in RadioCountToLeds, this will work:</p>

<pre>
(gdb) break *AMQueueImplP$0$Send$send
Breakpoint 5 at 0x8051b29: file AMQueueImplP.nc, line 79.
</pre>

<p>If you have multiple instances of a generic in a 
program, there is unfortunately no easy way to figure out each one's
name besides looking at the source code or stepping into them.
E.g., if you application uses serial and radio communication,
knowing which stack has AMQueueImpl$0 and which has AMQueueImplP$1
requires either stepping through their send operation or looking
at their <code>app.c</code> files.
</p>

<h1>Conclusions</h1>

This lesson introduced the basics of the TOSSIM simulator. It showed
you how to configure a network, how to run a simulation, how to
inspect variables, how to inject packets, and how to compile with C++.

<center>
<p>&lt;&nbsp;<b><a href="lesson10.html">Previous Lesson</a></b> |&nbsp; <b><a
 href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson12.html">Next
Lesson </a>&nbsp;&gt;</b>
	      </center>
</p>


	    <A name="appendix"><H1>Appendix A: Troubleshooting TOSSIM compilation</H1></A>

	    <p>TOSSIM is a C/C++ shared library with an optional
	    Python translation layer. Almost all of the problems
	    encountered in compiling TOSSIM are due to C linking
	    issues. If you don't know what a linker is (or have never
	    linked a C program), then chances are the rest of this
	    appendix is going to be cryptic and
	    incomprehensible. You're best off starting with learning
	    about <A
	    HREF="http://en.wikipedia.org/wiki/Linker">linkers</A>, <A
	    HREF="http://www.iecc.com/linker/linker01.html">why they
	    are needed</A>, and how you <A
	    HREF="http://www.linuxjournal.com/article/6463">use the
	    gcc/g++ compilers</A> to link code.</p>
		

	    <p>Generally, when compiling TOSSIM using <tt>make micaz sim</tt>,
	      one of four things can go wrong:</p>

	    <ol>
	      <li>You are using Cygwin but the <tt>sim</tt> compilation option
		can't figure this out.</li>

	      <li>You do not have the needed Python support installed.</li>

	      <li>You have Python support installed, but the make
	      system can't find it.</li>

	      <li>You have Python support installed, but it turns out to
		be incompatible with TOSSIM.</li>
              
	       <li>You have a variant of gcc/g++ installed that 
	        expects slightly different compilation options than the
		normal installation.</li>
	    </ol>

	    <p>We'll visit each in turn.</p>

	    <h2>You are using Cygwin but the <tt>sim</tt> compilation option
	      can't figure this out</h2>

	    <p>It turns out that the Cygwin and Linux versions of gcc/g++
	      have different command-line flags and require different options
	      to compile TOSSIM properly. For example, telling the Linux
	      compiler to build a library requires <tt>-fPIC</tt> while
	      the Cygwin is <tt>-fpic</tt>. If you're using Cygwin and
	      you see the output look like this:

	      <pre>
  ncc -c -shared -fPIC -o build/micaz/sim.o ...
	      </pre>

	      rather than

	      <pre>
  ncc -c -DUSE_DL_IMPORT -fpic -o build/micaz/sim.o ...
	      </pre>

	      then you have encountered this problem. The problem
	      occurs because Cygwin installations do not have a
	      consistent naming scheme, and so it's difficult for the
	      compilation toolchain to always figure out whether it's
	      under Linux or Cygwin.</p>

	    <p><b>Symptom:</b> You're running cygwin but you see the
	      <tt>-fPIC</tt> rather than <tt>-fpic</tt> option being
	      passed to the compiler.</b></p>
	    
	    <p><b>Solution:</b> Explicitly set the OSTYPE environment
	      variable to be <tt>cygwin</tt> either in your <tt>.bashrc</tt>
	      or when you compile. For example, in bash:</p>

	    <pre>
$ OSTYPE=cygwin make micaz sim
	    </pre>

	    or in tcsh

	    <pre>
$ setenv OSTYPE cygwin
$ make micaz sim
	    </pre>

	    <p>Note that often this problem occurs in addition to
	    other ones, due to using a nonstandard Cygwin
	    installation. So you might have more problems to track
	    down.</p>
	    
	    <h2>You do not have the needed Python support installed</h2>

	    <p>If when you compile you see lots of errors such as
	    "undefined reference to" or "Python.h: No such file or
	    directory" then this might be your problem. It is a
	    subcase of the more general problem of TOSSIM not being
	    able to find needed libraries and files.</p>
	    
	    <p>Compiling Python scripting support requires that you
	      have certain Python development libraries installed. First, check
	      that you have Python installed:</p>

	    <pre>
$ python -V
Python 2.4.2
	    </pre>

	    <p>In the above example, the system has Python 2.4.2. If
	    you see "command not found" then you do not have Python
	    installed. You'll need to track down an RPM and install
	    it.  TOSSIM has been tested with Python versions 2.3 and
	    2.4. You can install other versions, but there's no
	    assurance things will work.</p>

	    <p>In addition to the Python interpreter itself, you need
	    the libraries and files for Python development. This is
	    essentially a set of header files and shared libraries. If
	    you have the <tt>locate</tt> command, you can type
	    <tt>locate libpython</tt>, or if you don't, you can look
	    in <tt>/lib</tt>, <tt>/usr/lib</tt> and
	    <tt>/usr/local/lib</tt>. You're looking for a file with a
	    name such as <tt>libpython2.4.so</tt> and a file named
	    <tt>Python.h</tt>. If you can't find these files, then you
	    need to install a <tt>python-devel</tt> package.</p>


	    <p><b>Symptom:</b> Compilation can't find critical files
	    such as the Python interpreter, <tt>Python.h</tt> or a
	    Python shared library, and searching your filesystem shows
	    that you don't have them.</p>

	    <p><b>Solution:</b> Installed the needed files from Python
	    and/or Python development RPMS.</p>

	    <p>If you have all of the needed files, but are still
	    getting errors such as "undefined reference" or "Python.h:
	    No such file or directory", then you have the next
	    problem: they're on your filesystem, but TOSSIM can't find
	    them.</p>
	      
	    <h2>You have Python support installed, but the make
	      system can't find it</h2>

	    <p>You've found libpython and Python.h, but when TOSSIM compiles
	    it says that it can't find one or both of them. If it can't
	    find Python.h then compilation will fail pretty early, as g++ won't
	    be able to compile the Python glue code. If it can't find the python
	    library, then compilation will fail at linking, and you'll see
	    errors along the lines of "undefined reference to __Py...". You
	    need to point the make system at the right place.</p>

	    <p>Open up <tt>support/make/sim.extra</tt>. If the make
	      system can't find Python.h, then chances are it isn't in
	      one of the standard places (e.g., /usr/include). You need to tell
	      the make system to look in the directory where Python.h is with
	      a <tt>-I</tt> option. At the top of sim.extra, under the PFLAGS entry,
	      add

	    <pre>
CFLAGS += -I/path
	    </pre>

	      where <tt>/path</tt> is the path of the directory where Python.h
	      lives. For example, if it is in <tt>/opt/python/include</tt>,
	      then add <tt>CFLAGS += -I/opt/python/include</tt>.</p>
	    
	    <p>If the make system can't find the python library for
	    linking (causing "undefined reference") error messages,
	    then you need to make sure the make system can find
	    it. The sim.extra file uses two variables to find the
	    library: <tt>PYDIR</tt> and <tt>PYTHON_VERSION</tt>.  It
	    looks for a file named libpython$(PYTHON_VERSION).so. So
	    if you have Python 2.4 installed, make sure that
	    PYTHON_VERSION is 2.4 (be sure to use no spaces!) and if
	    2.3, make sure it is 2.3.</p>

	    <p>Usually the Python library is found in
	    <tt>/usr/lib</tt>. If it isn't there, then you will need
	    to modify the <tt>PLATFORM_LIB_FLAGS</tt> variable.  The
	    -L flag tells gcc in what directories to look for
	    libraries. So if libpython2.4.so is in
	    <tt>/opt/python/lib</tt>, then add
	    <tt>-L/opt/python/lib</tt> to the
	    <tt>PLATFORM_LIB_FLAGS</tt>. Note that there are three
	    different versions of this variable, depending on what OS
	    you're using. Be sure to modify the correct one (or be
	    paranoid and modify all three).

	      
	    <p><b>Symptom:</b> You've verified that you have the
	    needed Python files and libraries, but compilation is
	    still saying that it can't link to them ("undefined
	    reference") or can't find them ("cannot find -lpython2.4").</p>

	    <p><b>Solution:</b> Change the sim.extra file to point to
	    the correct directories using -L and -I flags.</p>

	    <h2>You have Python support installed, but it turns out to
	      be incompatible with TOSSIM.</h2>

	    <p><b>Symptom:</b> You get a "This python version requires
	      to use swig with the -classic option" error message.</p>

	    <p><b>Solution:</b> Install SWIG and regenerate Python
	    support with the sing-generate script in
	    <tt>tos/lib/tossim</tt>, or install a different version of
	    Python.</p>
	    
	       <h2>You have a variant of gcc/g++ installed that 
	        expects slightly different compilation options than the
		normal installation.</h2>

		<p><b>Symptom:</b> g++ complains that it cannot find
		 main() when you are compiling the shared library
		 ("undefined reference to `_WinMain@16'").</p>

		 <p><b>Solution:</b> There are two possible solutions.
		 The first is to include a dummy main(), as described
		  in this <A HREF="http://mail.millennium.berkeley.edu/pipermail/tinyos-help/2006-December/021719.html">tinyos-help posting.</A> The
		  second is to add the -shared option, as described in
		  this <A HREF="http://curl.haxx.se/mail/archive-2003-01/0056.html">web page</A>.
		  
		  <p>Hopefully, these solutions worked and you can get back
	    to <A HREF="#compiling">compiling</A>, If not, then you
		should email tinyos-help.</p>
</center>

</body>
</html>
